package com.ton.system.controller;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hai.admin.table.vo.Result;
import com.ton.config.annotation.Permission;
import com.ton.config.annotation.PermissionGuest;
import com.ton.config.data.AdminLoginUser;
import com.ton.system.entity.AdminPermission;
import com.ton.system.entity.AdminUser;
import com.ton.system.entity.LoginCenterConfigVo;
import com.ton.system.service.AdminUserService;
import com.ton.utils.AccessUtil;
import com.ton.utils.CacheUtil;
import com.ton.utils.JWTUtil;
import com.kypj.frame.common.DateUtil;
import com.kypj.frame.common.EmptyUtil;
import com.kypj.frame.common.MD5Util;
import com.kypj.frame.common.RandomUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@RestController
@RequestMapping("/admin")
@Api(value = "登录控制器",tags = "登录控制器")
public class AdminLoginController {
    @Resource
    private AdminUserService adminUserService;

    @PostMapping("/createVerifyCode")
    @Permission("user:add")
    @ApiOperation(value = "创建验证码",notes = "创建验证码")
    public Result createVerifyCode(String verifyCode) {
        String code = RandomUtil.getRandomNumber(6);
        CacheUtil.cacheObject("createVerifyCode_" + code, code, 300);
        Result result = new Result();
        return result.addData("code", code);
    }


    @PostMapping("/clearDevice")
    @Permission("user:add")
    @ApiOperation(value = "清除设备信息",notes = "清除设备信息")
    public Result clearDevice(Integer userId) {
        adminUserService.clearDevice(userId);
        return new Result().setSuccessMsg("操作成功");
    }

    //@RequestMapping("/checkIp")
    @GetMapping("/checkIp")
    @PermissionGuest
    @ApiOperation(value = "检查IP",notes = "检查IP")
    public Result checkIp(String href) {
        Result result = new Result();
        if (isLocalLogin(href)) {
            return result;
        }
        LoginCenterConfigVo configVo = adminUserService.getLoginCenterConfigVo();
        if (configVo != null && configVo.isCloseAcctPwdLogin()) {
            return result.setErrorMsg("无效的IP");
        }
        return result;
    }

    private boolean isLocalLogin(String href) {
        if (href != null &&
                (href.startsWith("http://127.0.0.1")
                        || href.startsWith("http://192.168.0") ||
                        href.startsWith(":http://192.168.1")
                        || href.startsWith("http://localhost"))) {
            return true;
        }
        return false;
    }

    @PostMapping("/login")
    @PermissionGuest
    @ApiOperation(value = "用户登录",notes = "用户登录")
    public Result login(String username, String password, String deviceId, String code, String authenToken, String href) {
        Result result = new Result();
        LoginCenterConfigVo configVo = adminUserService.getLoginCenterConfigVo();
        boolean acctLogin = true;
        if (configVo != null && authenToken != null && authenToken.length() > 6) {
            acctLogin = false;
            String postUrl = configVo.getValidateUrl() + "/token/validate";
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("token", authenToken);
            String json = HttpUtil.createPost(postUrl).timeout(60000).body(jsonObject.toJSONString()).execute().body();
            JSONObject rep = JSON.parseObject(json);
            if (rep.getIntValue("code") != 200) {
                return result.setErrorMsg("TOKEN无效，登录失败！");
            }
            JSONObject data = rep.getJSONObject("data");
            Integer appAcctId = data.getInteger("appAcctId");
            String appAcct = data.getString("appAcct");
            String appCode = data.getString("appCode");
            if (!Objects.equals(appCode, configVo.getAppCode())) {
                return result.setErrorMsg("TOKEN无效，登录失败！");
            }
            username = appAcct;
        } else if (configVo != null && configVo.isCloseAcctPwdLogin()) {
            if (isLocalLogin(href)) {
                acctLogin = true;
            } else {
                return result.setErrorMsg("账号登录通道已关闭！");
            }
        } else if (EmptyUtil.isEmpty(username)) {
            return result.setErrorMsg("用户名或密码错误！");
        }

        AdminUser adminUser = adminUserService.findAdminUserByLoginName(username);
        if (acctLogin) {
            if (adminUser == null || password == null || !MD5Util.md5(password).equals(adminUser.getPasswd())) {
                return result.setErrorMsg("用户名或密码错误！");
            }
            if (adminUser.getFlag() != 0) {
                return result.setErrorMsg("账户停用，禁止登陆！");
            }
        } else {
            if (adminUser == null) {
                return result.setErrorMsg("登录失败，token检验失败！");
            }
        }


        Integer adminId = adminUser.getId();
        List<String> permissionsList = new ArrayList<>();
        List<AdminPermission> listPerms = adminUserService.listAdminPermissionByUserId(adminId);
        for (AdminPermission permission : listPerms) {
            if (permission.getPermission().indexOf(",") > 0) {
                String[] arr = permission.getPermission().split(",");
                for (String p : arr) {
                    if (EmptyUtil.isNotEmpty(p)) {
                        permissionsList.add(p);
                    }
                }
            } else {
                permissionsList.add(permission.getPermission());
            }
        }
        if (permissionsList.isEmpty()) {
            return result.setErrorMsg("当前账户没有权限，请管理员授权！");
        }

        if (code != null && code.length() >= 3) {
            String verify = CacheUtil.queryObject("createVerifyCode_" + code);
            if (verify != null || code.equals(adminUser.getFixVerifyCode())) {
                CacheUtil.removeObject("createVerifyCode_" + code);
                String devId = DateUtil.formatDate(new Date(), "yyyyMMddHHmmss") + "M" + RandomUtil.getRandomChar(10);
                if (EmptyUtil.isEmpty(adminUser.getDeviceIds())) {
                    adminUser.setDeviceIds(devId);
                } else {
                    List<String> list = new ArrayList<String>();
                    for (String dev : adminUser.getDeviceIds().split(",")) {
                        if (!EmptyUtil.isEmpty(dev)) {
                            list.add(dev);
                        }
                    }
                    list.add(devId);
                    if (list.size() > adminUser.getMaxDevice()) {
                        list.remove(0);
                    }
                    if (list.size() > adminUser.getMaxDevice()) {
                        list.remove(0);
                    }
                    adminUser.setDeviceIds(String.join(",", list));
                }
                result.addData("deviceId", devId);
            } else {
                //return result.setErrorMsg("设备认证码不正确").addData("showInputCode", true);
            }

        } else if (adminUser.getDeviceIds() == null || deviceId == null || deviceId.length() < 10 || adminUser.getDeviceIds().indexOf(deviceId) == -1) {
            // return result.setErrorMsg("该设备不允许登录，需要设备认证码，请联系管理员").addData("showInputCode", true);
        }
        adminUser.setLoginTime(new Date());
        adminUserService.updateAdminUser(adminUser);
        CacheUtil.cacheObject("admin_permission_" + adminId, permissionsList, 3600 * 24);
        AdminLoginUser user = new AdminLoginUser();
        user.setUserId(adminId);
        user.setKey(RandomUtil.getRandomChar(12));
        user.setExp(System.currentTimeMillis() + 1000 * 3600L * 12 * 1);
        CacheUtil.cacheObject("admin_session_key_" + adminId, user.getKey(), 3600);
        String token = JWTUtil.generate(user);
        result.addData("token", token);

        return result;
    }

    @GetMapping("/logout")
    @PermissionGuest
    @ApiOperation(value = "用户登出",notes = "用户登出")
    public Result logout(String username, String password) {
        Result result = new Result();
        return result;
    }

    @GetMapping("/userinfo")
    @ApiOperation(value = "获取用户信息",notes = "获取用户信息")
    public Result userinfo() {
        Integer adminId = AccessUtil.getAdminLoginUserId();
        AdminUser adminUser = adminUserService.findAdminUserById(adminId);
        List<String> permissions = CacheUtil.queryObject("admin_permission_" + adminId);
        Result result = new Result();
        result.addData("name", adminUser.getPersonName());
        result.addData("permissions", permissions);
        return result;
    }


}
